{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 571,
   "id": "899b1b9b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "import sys\n",
    "import os\n",
    "import math\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import pandas_ta as ta\n",
    "import datetime\n",
    "from pandas.tseries.holiday import USFederalHolidayCalendar\n",
    "from pandas.tseries.offsets import CustomBusinessDay\n",
    "US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar())\n",
    "import matplotlib.pyplot as plt\n",
    "import plotly.graph_objects as go\n",
    "from plotly.subplots import make_subplots\n",
    "import itertools\n",
    "import matplotlib.dates as mpl_dates\n",
    "import yfinance as yf\n",
    "from os.path import exists\n",
    "from pycoingecko import CoinGeckoAPI\n",
    "from IPython import display\n",
    "import time\n",
    "from yattag import Doc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 572,
   "id": "d95483d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_trending_results(cg):\n",
    "    results_df = pd.DataFrame()\n",
    "    response = cg.get_search_trending()\n",
    "    trending_list = response['coins']\n",
    "    for obj in trending_list:\n",
    "        #  Parse trending results\n",
    "        item = obj['item']\n",
    "        item_row = pd.DataFrame({'id': [item['id']], 'name':[item['name']],'symbol': [item['symbol']],'market_cap_rank': [item['market_cap_rank']],'thumb': [item['thumb']]})\n",
    "        results_df = pd.concat([results_df, item_row], axis=0, ignore_index=True)\n",
    "    return results_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 573,
   "id": "843b7448",
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_candlestick(coin_id, df, period):\n",
    "    plot_info = f\"{coin_id}-ohlc-{period}\"\n",
    "    fig = make_subplots(rows=1, cols=1, subplot_titles=[plot_info])\n",
    "\n",
    "    #  Plot close price\n",
    "    fig.add_trace(go.Candlestick(x=df['epoch'],\n",
    "                open=df['open'],\n",
    "                high=df['high'],\n",
    "                low=df['low'],\n",
    "                close=df['close']), row = 1, col = 1) \n",
    "    \n",
    "    fig.update_layout(\n",
    "        title={'text':'', 'x':0.5},\n",
    "        autosize=False,\n",
    "        width=800,height=600)\n",
    "    fig.update_yaxes(range=[0,1000000000],secondary_y=True)\n",
    "    fig.update_yaxes(visible=False, secondary_y=True)  #hide range slider\n",
    "    \n",
    "    #fig.show()\n",
    "    fig.write_image(f\"{plot_info}.png\", format=\"png\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 574,
   "id": "8dbf368c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_coin_info(cg, coin_id):\n",
    "    response = cg.get_coin_by_id(coin_id)\n",
    "    categories = response['categories']\n",
    "    public_notice = response['public_notice']\n",
    "    name = response['name']\n",
    "    description = response['description']['en']\n",
    "    links = response['links']\n",
    "    homepage_link = links['homepage']\n",
    "    blockchain_site = \",\".join(links['blockchain_site'])\n",
    "    official_forum_url = links['official_forum_url']\n",
    "    chat_url = links['chat_url']\n",
    "    announcement_url = links['announcement_url']\n",
    "    twitter_screen_name = links['twitter_screen_name']\n",
    "    facebook_username = links['facebook_username']\n",
    "    telegram_channel_identifier = links['telegram_channel_identifier']\n",
    "    subreddit_url = links['subreddit_url']\n",
    "    sentiment_votes_up_percentage = response['sentiment_votes_up_percentage']\n",
    "    sentiment_votes_down_percentage = response['sentiment_votes_down_percentage']\n",
    "    market_cap_rank = response['market_cap_rank']\n",
    "    coingecko_rank = response['coingecko_rank']\n",
    "    coingecko_score = response['coingecko_score']\n",
    "    community_score = response['community_score']\n",
    "    liquidity_score = response['liquidity_score']\n",
    "    public_interest_score = response['public_interest_score']\n",
    "    \n",
    "    row = pd.DataFrame({'id':[coin_id],'name':[name],'categories': [categories],'public_notice':[public_notice],\\\n",
    "                       'description': [description],'homepage_link': [homepage_link], \\\n",
    "                       'blockchain_site':[blockchain_site],'official_forum_url':[official_forum_url], \\\n",
    "                       'chat_url': [chat_url],'announcement_url':[announcement_url], \\\n",
    "                       'twitter_screen_name':[twitter_screen_name],'facebook_username':[facebook_username], \\\n",
    "                       'telegram_channel_identifier': [telegram_channel_identifier],'subreddit_url':[subreddit_url], \\\n",
    "                       'sentiment_votes_up_percentage':[sentiment_votes_up_percentage], \\\n",
    "                       'sentiment_votes_down_percentage':[sentiment_votes_down_percentage], \\\n",
    "                       'market_cap_rank': [market_cap_rank], \\\n",
    "                       'coingecko_rank': [coingecko_rank], \\\n",
    "                       'coingecko_score':[coingecko_score],'coingecko_score': [coingecko_score], \\\n",
    "                       'community_score':[community_score],'liquidity_score': [liquidity_score], \\\n",
    "                       'public_interest_score':[public_interest_score]})\n",
    "    row = row.set_index('id')\n",
    "    return row"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 575,
   "id": "0c53b544",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_ohlc(cg, coin_id, vs_currency, days):\n",
    "    response = cg.get_coin_ohlc_by_id(coin_id, vs_currency=\"usd\", days=days)\n",
    "    \n",
    "    ohlc_df = pd.DataFrame()\n",
    "    for ohlc in response:\n",
    "        epoch = ohlc[0]\n",
    "        #timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(epoch))\n",
    "        #time = datetime.datetime.utcfromtimestamp(epoch).strftime('%Y-%m-%d %H:%M:%S')\n",
    "        row = pd.DataFrame({'epoch':[ohlc[0]],'open':[ohlc[1]],'high':[ohlc[2]],'low':[ohlc[3]],'close':[ohlc[4]]})\n",
    "        ohlc_df = pd.concat([ohlc_df, row], axis=0, ignore_index=True)\n",
    "        \n",
    "    return ohlc_df\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 576,
   "id": "fd407710",
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_coin_section(coin_id, coin_info_df):\n",
    "    doc, tag, text = Doc().tagtext()\n",
    "    with tag('h1'):\n",
    "        text(f\"{coin_id} report\")\n",
    "\n",
    "    return doc.getvalue()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 577,
   "id": "dfdf3e1b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_report(coin_ids, info_map):\n",
    "    #doc, tag, text, line = Doc().tagtext()\n",
    "    doc, tag, text, line = Doc().ttl()\n",
    "    now_str = datetime.datetime.now().strftime(\"%d/%m/%Y %H:%M:%S\") \n",
    "    \n",
    "    with tag('html'):\n",
    "        with tag('head'):\n",
    "            with tag('style'):\n",
    "                    text(\"\"\"div{ width: 100%; }\n",
    "                        html { margin: 0; padding: 10px; background: #1e81b0;}\n",
    "                        body { font: 12px verdana, sans-serif;line-height: 1.88889; margin: 5%; background: #ffffff; padding: 1%; width: 90%; }\n",
    "                        p { margin-top: 5px; text-align: justify; font: normal 0.9em verdana, sans-serif;color:#484848}\n",
    "                        li { font: normal 0.8em verdana, sans-serif;color:#484848}\n",
    "                        h1 { font: normal 1.8em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #063970,}\n",
    "                        h2 { font: normal 1.6em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #154c79}\n",
    "                        h3 { font: normal 1.6em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #154c79}\n",
    "                        p.bold_text{ font: normal 0.9em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #154c79; font-weight: bold}\"\"\")\n",
    "\n",
    "        with tag('body', id = 'body'):\n",
    "            with tag('h1'):\n",
    "                text(f\"Trending Crypto Report for {now_str}\")\n",
    "            with tag('hr'):\n",
    "                text('')\n",
    "\n",
    "            for coin_id in coin_ids:\n",
    "                coin_df = info_map[coin_id]\n",
    "                with tag('h2'):\n",
    "                    text(f\"{coin_id.upper()}\")\n",
    "                with tag('div'):\n",
    "                    line('p',f\"Name: {coin_df['name'].values[0]}\",klass=\"bold_text\")\n",
    "                    line('p',coin_df['name'].values[0])\n",
    "                    line('p',f\"Description:\",klass=\"bold_text\")\n",
    "                    line('p',coin_df['description'].values[0])\n",
    "                    line('p',f\"Categories:\",klass=\"bold_text\")\n",
    "                    category_list = \"\"\n",
    "                    if coin_df['categories'].values[0] is not None:\n",
    "                        for category_str in coin_df['categories'].values[0]:\n",
    "                            if category_str is None:\n",
    "                                continue\n",
    "                            if len(category_list) > 0:\n",
    "                                category_list += \", \"\n",
    "                            category_list += category_str \n",
    "                    line('p',f\"{category_list}\")\n",
    "                    line('p',f\"Public Notice:\",klass=\"bold_text\")\n",
    "                    line('p',f\"{coin_df['public_notice'].values[0]}\")\n",
    "                    line('p',f\"Links:\",klass=\"bold_text\")\n",
    "                    with tag('ul', id='links-list'):\n",
    "                        url_list = \"\"\n",
    "                        if coin_df['homepage_link'].values[0] is not None:\n",
    "                            for link_str in coin_df['homepage_link'].values[0]:\n",
    "                                url_list += link_str\n",
    "                        line('li', f\"Home Page: {url_list}\")\n",
    "                        line('li', f\"Blockchain Site: {coin_df['blockchain_site'].values[0]}\")\n",
    "                        url_list = \"\"\n",
    "                        if coin_df['official_forum_url'].values[0] is not None:\n",
    "                            for link_str in coin_df['official_forum_url'].values[0]:\n",
    "                                url_list += link_str\n",
    "                        line('li', f\"Official Forum URLs: {url_list}\")\n",
    "                        url_list = \"\"\n",
    "                        if coin_df['chat_url'].values[0] is not None:\n",
    "                            for link_str in coin_df['chat_url'].values[0]:\n",
    "                                url_list += link_str                       \n",
    "                        line('li', f\"Chat URLs: {url_list}\")\n",
    "                    line('p',f\"Social Media:\",klass=\"bold_text\")\n",
    "                    with tag('ul', id='social-list'):\n",
    "                        line('li', f\"Twitter: {coin_df['twitter_screen_name'].values[0]}\")\n",
    "                        line('li', f\"Facebook: {coin_df['facebook_username'].values[0]}\")\n",
    "                        line('li', f\"Telegram: {coin_df['telegram_channel_identifier'].values[0]}\")\n",
    "                    line('p',f\"Sentiment:\",klass=\"bold_text\")\n",
    "                    with tag('ul', id='sentiment-list'):\n",
    "                        line('li', f\"Votes Up: {coin_df['sentiment_votes_up_percentage'].values[0]}\")\n",
    "                        line('li', f\"Votes Down: {coin_df['sentiment_votes_down_percentage'].values[0]}\")\n",
    "                    line('p',f\"Ranks:\",klass=\"bold_text\")\n",
    "                    with tag('ul', id='sentiment-list'):\n",
    "                        line('li', f\"Market Cap Rank: {coin_df['market_cap_rank'].values[0]}\")\n",
    "                        line('li', f\"Gecko Rank: {coin_df['coingecko_rank'].values[0]}\")\n",
    "                        line('li', f\"Gecko Score: {coin_df['coingecko_score'].values[0]}\")\n",
    "                        line('li', f\"Community Score: {coin_df['community_score'].values[0]}\")\n",
    "                        line('li', f\"Public Interest Score: {coin_df['public_interest_score'].values[0]}\")\n",
    "                    with tag('div', id='photo-container'):\n",
    "                        line('p',f\"Day Plot:\",klass=\"bold_text\")\n",
    "                        doc.stag('img', src=f\"{coin_id}-ohlc-day.png\", klass=\"day_plot\")\n",
    "                        line('p',f\"Month Plot:\",klass=\"bold_text\")\n",
    "                        doc.stag('img', src=f\"{coin_id}-ohlc-month.png\", klass=\"day_plot\")\n",
    "                    with tag('hr'):\n",
    "                        text('')\n",
    "\n",
    "    \n",
    "    #  Save report\n",
    "    report_file = open(\"trending-coins-report.html\", \"w\")\n",
    "    report_file.write(doc.getvalue() )\n",
    "    report_file.close()\n",
    "           "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 578,
   "id": "4a32147d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Report generation complete\n"
     ]
    }
   ],
   "source": [
    "#  Initialize client\n",
    "cg = CoinGeckoAPI()\n",
    "\n",
    "# Get trending crypto\n",
    "results_df = get_trending_results(cg)\n",
    "results_df['coin_id'] = results_df['id']\n",
    "results_df = results_df.set_index('id')\n",
    "\n",
    "#  Get coin info\n",
    "day_ohlc_map = {}\n",
    "month_ohlc_map = {}\n",
    "info_map = {}\n",
    "coin_ids = np.array(results_df['coin_id'])\n",
    "coin_sections_html = \"\"\n",
    "for coin_id in coin_ids:\n",
    "    info_df = get_coin_info(cg, coin_id)\n",
    "    info_map[coin_id] = info_df\n",
    "\n",
    "    #  Get daily prices - 30 min period\n",
    "    day_ohlc_df = get_ohlc(cg, coin_id, vs_currency='usd', days=1)\n",
    "    day_ohlc_map[coin_id] = day_ohlc_df\n",
    "    plot_candlestick(coin_id, day_ohlc_df, 'day')\n",
    "    \n",
    "    #  Get monthly prices - 4 hour period\n",
    "    month_ohlc_df = get_ohlc(cg, coin_id, vs_currency='usd', days=30)\n",
    "    month_ohlc_map[coin_id] = month_ohlc_df\n",
    "    plot_candlestick(coin_id, month_ohlc_df, 'month')\n",
    "\n",
    "#  Build report\n",
    "build_report(coin_ids, info_map)\n",
    "print('Report generation complete')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:tradesystem1]",
   "language": "python",
   "name": "conda-env-tradesystem1-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
